//Artigo de Kang 2004
#ifndef APROXIMATEDJACOBI_H
#define APROXIMATEDJACOBI_H
#include "integrationMethod.h"


class AproximatedJacobi : public IntegrationMethod
{
    public:

        AproximatedJacobi();

        AproximatedJacobi(double, double, std::vector<State>, std::vector< std::vector<Particle *> > &, std::vector< std::vector<Spring *> > &, bool, int, double,  double,  double, Vector3D);

        ~AproximatedJacobi();

        void calculate(bool, unsigned int, double); //calculate the new state



    private:

        Matrix populateMatrixMass(const State&, unsigned int, unsigned int); //calculating the mass matrix of given particle

        Matrix *derivativeForcePosition(const State& _state, Spring*, const Vector3D&, const Vector3D&, const Vector3D&, const Vector3D&, unsigned int); //calculate the Jacobian relating the position

        std::vector<Matrix*> vectorOfJacobianPosition( const State&, const Vector3D&, const Vector3D&, unsigned int, unsigned int); //returns an array containing all the Jacobian matrices related to a given particle

        Matrix derivatedForcePositionItself(const std::vector<Matrix*>&, unsigned int, unsigned int); //calculates the Jacobian matrix with respect to the position of the particle itself

        Vector3D forceResultanteParticle(const State&, const Vector3D&, const Vector3D&, const std::vector<Matrix*>&, unsigned int, unsigned int); //calculating the force f~ (equation 7)

        //Matrix *derivativeForceVelocity(const State&, Spring *, unsigned int); //calculate the Jacobian relating the velocity
        Matrix *derivativeForceVelocity(const State&, Spring *, const Vector3D&, const Vector3D&, unsigned int); //calculate the Jacobian relating the velocity

        //std::vector<Matrix*> vectorOfJacobianVelocity(const State&, unsigned int, unsigned int); //returns an array containing all the Jacobian matrices related to a given particle
        std::vector<Matrix*> vectorOfJacobianVelocity(const State&, const Vector3D&, unsigned int, unsigned int); //returns an array containing all the Jacobian matrices related to a given particle

        Matrix derivativeForceVelocityItself(const std::vector<Matrix*>&, unsigned int, unsigned int); //calculates the Jacobian matrix with respect to the velocity of the particle itself

        void calculateAproximatedJacobi(State*,  const Vector3D&, const Vector3D&, const Vector3D&, unsigned int); //calculate the new position and speed


};
#endif // APROXIMATEDJACOBI_H
